package com.rc.saas.mini.service.member;


import com.alibaba.fastjson.JSON;
import com.rc.saas.mini.common.base.DataTResponse;
import com.rc.saas.mini.common.mq.MqConfig;
import com.rc.saas.mini.common.mq.MqProducer;
import com.rc.saas.mini.mapper.member.MemberRefundApplyMapper;
import com.rc.saas.mini.model.member.MemberAccount;
import com.rc.saas.mini.model.member.MemberAccountRecord;
import com.rc.saas.mini.model.member.MemberRefundApply;
import com.rc.saas.mini.model.rc.RcMsgNotification;
import com.rc.saas.mini.model.tenant.TenantTransfer;
import com.rc.saas.mini.service.order.OrderInfoService;
import com.rc.saas.mini.service.rc.RcMsgNotificationService;
import com.rc.saas.mini.service.tenant.TenantTransferService;
import com.rc.saas.mini.vo.member.MemberRefundFactVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

@Service
public class MemberRefundApplyServiceImpl implements MemberRefundApplyService {
    @Autowired
    private MemberRefundApplyMapper memberRefundApplyMapper;

    @Autowired
    private TenantTransferService tenantTransferService;

    @Autowired
    private MemberInfoService memberInfoService;

    @Autowired
    private OrderInfoService orderInfoService;


    @Autowired
    private MemberAccountService memberAccountService;

    @Autowired
    private MemberAccountRecordService memberAccountRecordService;

    @Autowired
    private MqProducer mqProducer;

    @Autowired
    private RcMsgNotificationService rcMsgNotificationService;


    @Override
    public MemberRefundApplyMapper getMapper() {
        return memberRefundApplyMapper;
    }

    @Override
    public void insertByReturnId(MemberRefundApply memberRefundApply) {
        memberRefundApplyMapper.insertByReturnId(memberRefundApply);
    }

    @Override
    public List<MemberRefundApply> listByCondition(MemberRefundApply memberRefundApply) {
        return memberRefundApplyMapper.listByCondition(memberRefundApply);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DataTResponse selectFactAmount(MemberRefundApply memberRefundApply) {
        //提现规则
        TenantTransfer tenantTransfer = tenantTransferService.selectByTenantCode(memberRefundApply.getTenantCode());
        //当日成功条数
        List<MemberRefundApply> memberRefundApplyList = memberRefundApplyMapper.listByDaySuccess(memberRefundApply.getMemberId());
        int hasCount = memberRefundApplyList.size();
        BigDecimal hasAmount = memberRefundApplyList.stream().map(MemberRefundApply::getRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        //计算实际到账，用户手续费，当前
        //(value = "手续费类型(0:按比例算,1:按单笔算 默认0)")
        //手续费计算 0
        BigDecimal fee = BigDecimal.ZERO;
        if ("0".equals(tenantTransfer.getFormalitiesType())) {
            fee = memberRefundApply.getRefundAmount()
                    .multiply(new BigDecimal(tenantTransfer.getSingleProportion())
                            .divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_UP);
        } else {
            fee = new BigDecimal(tenantTransfer.getSingleCost());
        }

        BigDecimal refundAmount = BigDecimal.ZERO;
        BigDecimal factAmount = BigDecimal.ZERO;
        //(0:提现金额扣除，1:账户余额扣除
        if ("0".equals(tenantTransfer.getFormalitiesMode())) {
            refundAmount = memberRefundApply.getRefundAmount();
            factAmount = memberRefundApply.getRefundAmount().subtract(fee);
            if (factAmount.compareTo(BigDecimal.ZERO) <= 0) {
                return DataTResponse.FAIL("退款实际到账不足");
            }
        } else {
            //1:账户余额扣除
            factAmount = memberRefundApply.getRefundAmount();
            refundAmount = memberRefundApply.getRefundAmount().add(fee);

        }
        //核实最终数据
        memberRefundApply.setFaceAmount(factAmount);
        memberRefundApply.setRefundAmount(refundAmount);
        memberRefundApply.setServiceFee(fee);

        if (factAmount.compareTo(BigDecimal.ZERO) <= 0 || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return DataTResponse.FAIL("实际到手金额不足");
        }
        //条件判断
        if (hasCount >= tenantTransfer.getTodayTotalNum()) {
            return DataTResponse.FAIL("超过当日总次数");
        }

        if (memberRefundApply.getRefundAmount().compareTo(tenantTransfer.getSingleMinAmount()) < 0) {
            return DataTResponse.FAIL("小于单笔最小金额(元)");
        }

        MemberAccount memberAccount = memberAccountService.selectByPrimaryKey(memberRefundApply.getMemberId());

        //1.余额提现，直接计算
        if ("2".equals(memberRefundApply.getRefundMemberType())) {
            if (memberRefundApply.getRefundAmount().compareTo(tenantTransfer.getSingleMaxAmount()) > 0) {
                return DataTResponse.FAIL("大于单笔最大金额(元)");
            }
            if ((memberRefundApply.getRefundAmount().add(hasAmount)).compareTo(tenantTransfer.getTodayTotalAmount()) > 0) {
                return DataTResponse.FAIL("大于当日总金额(元)");
            }
            if (memberAccount.getAccount().compareTo(memberRefundApply.getRefundAmount()) < 0) {
                return DataTResponse.FAIL("余额不足");
            }
        } else if ("0".equals(memberRefundApply.getRefundMemberType())) {
            //2.渠道商计算
            if (memberAccount.getIncomeAmount().compareTo(memberRefundApply.getRefundAmount()) < 0) {
                return DataTResponse.FAIL("余额不足,提现金额及手续费大于余额。");
            }
        } else {
            return DataTResponse.FAIL("申请类型错误");
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String timeStamp = dateFormat.format(System.currentTimeMillis());

        //编码规则(22位): 支付方式(1位:R)+ 时间戳到毫秒17位+uuid后4位
        String num = "T" + timeStamp + StringUtils.right(UUID.randomUUID().toString(), 4);
        memberRefundApply.setOutTradeNo(num);
        //录入数据，推送审批，mq
        insertByReturnId(memberRefundApply);

        //余额扣减
        if ("2".equals(memberRefundApply.getRefundMemberType())) {
            //个人余额
            memberAccount.setAccount(memberAccount.getAccount().subtract(memberRefundApply.getRefundAmount()));
            memberAccount.setLastUpdatedTime(new Date());
            memberAccountService.updateByPrimaryKeySelective(memberAccount);

            //余额记录
            MemberAccountRecord memberAccountRecord = new MemberAccountRecord();
            BeanUtils.copyProperties(memberAccount, memberAccountRecord);
            //支付的账户类型 0个人钱包 1 企业钱包 2权益金 3收益金
            memberAccountRecord.setAccountType("0");
            memberAccountRecord.setAmount(memberRefundApply.getRefundAmount());
            memberAccountRecord.setResult(memberAccount.getAccount());


            //记录类型(0会员在线充值,1支出,2转账收入,3分配余额,4后台订单调整,5平台赠送,6积分兑换 7回收金额 8平台钱包充值 9分销返利 10资源占用费 11平台扣费 12 数据迁移 13共享额度变更 14后台退款 15.原路退款 16原路返还 ) 17.先付后退充值 18.先付后退退款
            memberAccountRecord.setRecordType("14");
            //本次变更金额
            memberAccountRecord.setSourceTradeNo(num);
            memberAccountRecord.setLocalTradeNo(num);
            memberAccountRecord.setRemark("提现");
            //0正常 1退款中 2退款成功 3退款失败'
            memberAccountRecord.setRefundStatus("1");
            memberAccountRecord.setCreatedTime(new Date());
            memberAccountRecord.setLastUpdatedTime(new Date());
            memberAccountRecordService.insertSelective(memberAccountRecord);
        } else {
            //收益金
            memberAccount.setIncomeAmount(memberAccount.getIncomeAmount().subtract(memberRefundApply.getRefundAmount()));
            memberAccount.setLastUpdatedTime(new Date());
            memberAccountService.updateByPrimaryKeySelective(memberAccount);

            //余额记录
            MemberAccountRecord memberAccountRecord = new MemberAccountRecord();
            BeanUtils.copyProperties(memberAccount, memberAccountRecord);
            //支付的账户类型 0个人钱包 1 企业钱包 2权益金 3收益金
            memberAccountRecord.setAccountType("3");
            memberAccountRecord.setAmount(memberRefundApply.getRefundAmount());
            memberAccountRecord.setResult(memberAccount.getIncomeAmount());


            //记录类型(0会员在线充值,1支出,2转账收入,3分配余额,4后台订单调整,5平台赠送,6积分兑换 7回收金额 8平台钱包充值 9分销返利 10资源占用费 11平台扣费 12 数据迁移 13共享额度变更 14后台退款 15.原路退款 16原路返还 ) 17.先付后退充值 18.先付后退退款
            memberAccountRecord.setRecordType("14");
            //本次变更金额
            memberAccountRecord.setSourceTradeNo(num);
            memberAccountRecord.setLocalTradeNo(num);
            memberAccountRecord.setRemark("提现");
            //0正常 1退款中 2退款成功 3退款失败'
            memberAccountRecord.setRefundStatus("1");
            memberAccountRecord.setCreatedTime(new Date());
            memberAccountRecord.setLastUpdatedTime(new Date());
            memberAccountRecordService.insertSelective(memberAccountRecord);
        }


        HashMap<String, Long> map = new HashMap<>();
        map.put("refundApplyId", memberRefundApply.getRefundApplyId());

        mqProducer.send(MqConfig.platform_apply, JSON.toJSONString(map));

        RcMsgNotification rcMsgNotification = new RcMsgNotification();
        rcMsgNotification.setTenantCode(memberRefundApply.getTenantCode());
        rcMsgNotification.setMsgType("4");
        rcMsgNotification.setMsgId(memberRefundApply.getRefundApplyId().toString());
        rcMsgNotificationService.saveRcMsgNotification(rcMsgNotification);
        return DataTResponse.SUCCESS("申请成功，48小时内到账。");
    }


    public DataTResponse<MemberRefundFactVo> sumFactAmount(MemberRefundApply memberRefundApply) {
        //提现规则
        TenantTransfer tenantTransfer = tenantTransferService.selectByTenantCode(memberRefundApply.getTenantCode());
        //当日成功条数
        List<MemberRefundApply> memberRefundApplyList = memberRefundApplyMapper.listByDaySuccess(memberRefundApply.getMemberId());
        int hasCount = memberRefundApplyList.size();
        BigDecimal hasAmount = memberRefundApplyList.stream().map(MemberRefundApply::getRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        //计算实际到账，用户手续费，当前
        //(value = "手续费类型(0:按比例算,1:按单笔算 默认0)")
        //手续费 0
        BigDecimal fee = BigDecimal.ZERO;
        if ("0".equals(tenantTransfer.getFormalitiesType())) {
            fee = memberRefundApply.getRefundAmount()
                    .multiply(new BigDecimal(tenantTransfer.getSingleProportion())
                            .divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_UP);
        } else {
            fee = new BigDecimal(tenantTransfer.getSingleCost());
        }

        BigDecimal refundAmount = BigDecimal.ZERO;
        BigDecimal factAmount = BigDecimal.ZERO;
        //(0:提现金额扣除，1:账户余额扣除
        if ("0".equals(tenantTransfer.getFormalitiesMode())) {
            refundAmount = memberRefundApply.getRefundAmount();
            factAmount = memberRefundApply.getRefundAmount().subtract(fee);
            if (factAmount.compareTo(BigDecimal.ZERO) <= 0) {
                return DataTResponse.FAIL("退款实际到账不足");
            }
        } else {

            factAmount = memberRefundApply.getRefundAmount();
            refundAmount = memberRefundApply.getRefundAmount().add(fee);

        }
        memberRefundApply.setFaceAmount(factAmount);
        memberRefundApply.setRefundAmount(refundAmount);
        memberRefundApply.setServiceFee(fee);

        //
        if (hasCount >= tenantTransfer.getTodayTotalNum()) {
            return DataTResponse.FAIL("超过当日总次数");
        }

        if (memberRefundApply.getRefundAmount().compareTo(tenantTransfer.getSingleMinAmount()) < 0) {
            return DataTResponse.FAIL("小于单笔最小金额(元)");
        }
        if (memberRefundApply.getRefundAmount().compareTo(tenantTransfer.getSingleMaxAmount()) > 0) {
            return DataTResponse.FAIL("大于单笔最大金额(元)");
        }
        if ((memberRefundApply.getRefundAmount().add(hasAmount)).compareTo(tenantTransfer.getTodayTotalAmount()) > 0) {
            return DataTResponse.FAIL("大于当日总金额(元)");
        }

        MemberAccount memberAccount = memberAccountService.selectByPrimaryKey(memberRefundApply.getMemberId());

        //1.余额提现，直接计算
        if ("2".equals(memberRefundApply.getRefundMemberType())) {
            if (memberAccount.getAccount().compareTo(memberRefundApply.getRefundAmount()) < 0) {
                return DataTResponse.FAIL("余额不足");
            }
        } else if ("0".equals(memberRefundApply.getRefundMemberType())) {
            //2.渠道商计算
            if (memberAccount.getIncomeAmount().compareTo(memberRefundApply.getRefundAmount()) != 0) {
                return DataTResponse.FAIL("余额不足,提现金额及手续费大于余额");
            }
        } else {
            return DataTResponse.FAIL("申请类型错误");
        }

        MemberRefundFactVo memberRefundFactVo = new MemberRefundFactVo();
        BeanUtils.copyProperties(memberRefundApply, memberRefundFactVo);
        return DataTResponse.SUCCESS_DATA(memberRefundFactVo);
    }

    @Override
    public List<MemberRefundApply> listByMemberNow(Long memberId) {
        return memberRefundApplyMapper.listByMemberNow(memberId);
    }
}
